package com.gdou.teaching.controller;

import com.gdou.teaching.Enum.ResultEnum;
import com.gdou.teaching.Enum.UserIdentEnum;
import com.gdou.teaching.Enum.UserStatusEnum;
import com.gdou.teaching.converter.UserInPutObjectConverter;
import com.gdou.teaching.dataobject.Clazz;
import com.gdou.teaching.dataobject.User;
import com.gdou.teaching.dto.UserDTO;
import com.gdou.teaching.exception.TeachingException;
import com.gdou.teaching.form.ClazzRegisterForm;
import com.gdou.teaching.form.ClazzUpdateForm;
import com.gdou.teaching.form.UserInPutObject;
import com.gdou.teaching.service.ClazzService;
import com.gdou.teaching.service.StudentService;
import com.gdou.teaching.service.UserService;
import com.gdou.teaching.util.ResultVOUtil;
import com.gdou.teaching.vo.ClazzVO;
import com.gdou.teaching.vo.ResultVO;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.Random;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * @author carrymaniac
 * @date Created in 14:43 2019-08-14
 * @description 班级类控制器
 **/
@Controller
@RequestMapping("/clazz")
@Slf4j
public class ClazzController {

    @Autowired
    ClazzService clazzService;
    @Autowired
    StudentService studentService;
    @Autowired
    UserService userService;

    @PostMapping("/createClazz")
    @ResponseBody
    public ResultVO<Clazz> createClazz(@Valid ClazzRegisterForm form, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            log.error("用户注册参数不正确：{}" + form);
            throw new TeachingException(ResultEnum.PARAM_ERROR.getCode(), ResultEnum.PARAM_ERROR.getMsg());
        }
        //1。注册班级
        String className = form.getClassName();
        Clazz clazz;
        try {
            clazz = clazzService.registerClass(className);
        } catch (TeachingException e) {
            return ResultVOUtil.fail(e.getCode(), e.getMessage());
        }
        //2。注册学生
        //2。1从表单中获取导入的学生数据。
        String studentInfos = form.getUserList();

        List<UserInPutObject> userInPutObjectList =
                UserInPutObjectConverter.String2ObjectList(studentInfos);

        List<User> userList =
                UserInPutObjectConverter.UserInPutObjectListConvert2UserList(userInPutObjectList, clazz.getClassId(), UserIdentEnum.SUTUDENT);

        //2。3 调用serivce新增
        try {
            userService.addUserByBatch(userList);
        } catch (TeachingException e) {
            return ResultVOUtil.fail(e.getCode(), e.getMessage());
        }
        return ResultVOUtil.success();
    }

    @GetMapping(value = "/info/{clazzId}")
    @ResponseBody
    public ResultVO<ClazzVO> detail(@PathVariable("clazzId") Integer clazzId) {
        //1.获取该班级的具体信息
        try {
            Clazz clazz = clazzService.getClassByClazzId(clazzId);
            //2。获取该班级的学生信息
            List<UserDTO> userList = studentService.getUserByClassId(clazz.getClassId());
            ClazzVO clazzVO = new ClazzVO();
            BeanUtils.copyProperties(clazz, clazzVO);
            clazzVO.setUserList(userList);
            return ResultVOUtil.success(clazzVO);
        } catch (TeachingException e) {
            return ResultVOUtil.fail(e.getCode(), e.getMessage());
        }
    }

    @GetMapping(value = "/list")
    @ResponseBody
    public ResultVO<List<ClazzVO>> list(@RequestParam(value = "page", defaultValue = "0") Integer page, @RequestParam(value = "size", defaultValue = "10") Integer size) {
        //1.获取全部的班级名单
        try {
            List<Clazz> classesByPage = clazzService.getClassesByPage(page, size);
            return ResultVOUtil.success(classesByPage);
        } catch (TeachingException e) {
            return ResultVOUtil.fail(e.getCode(), e.getMessage());
        }
    }

    @PostMapping(value = "/update")
    @ResponseBody
    public ResultVO<Clazz> updateClazz(@Valid ClazzUpdateForm form, BindingResult bindingResult) {

        //1。班级信息的修改
        if (bindingResult.hasErrors()) {
            log.error("班级信息更新参数不正确：{}" + form);
            return ResultVOUtil.fail(ResultEnum.PARAM_ERROR.getCode(), ResultEnum.PARAM_ERROR.getMsg());
        }
        String className = form.getClassName();
        Integer classId = form.getClassId();
        Clazz clazz = new Clazz();
        clazz.setClassName(className);
        clazz.setClassId(classId);
        try {
            boolean flag = false;
            //2。新增学生数据操作
            if (!StringUtils.isEmpty(form.getUserListForInsert())) {
                //需要增加学生
                List<UserInPutObject> userListForInsert = UserInPutObjectConverter.String2ObjectList(form.getUserListForInsert());
                List<User> userList = UserInPutObjectConverter.UserInPutObjectListConvert2UserList(userListForInsert, classId, UserIdentEnum.SUTUDENT);
                //调用serivce新增
                userService.addUserByBatch(userList);
                flag = true;
            }
            //3.删除学生数据操作
            if (!StringUtils.isEmpty(form.getUserListForDel())) {
                //需要删除学生
                List<UserInPutObject> userListForDel = UserInPutObjectConverter.String2ObjectList(form.getUserListForDel());
                List<String> userNumberForDel = userListForDel.stream().map(UserInPutObject::getUserNumber).collect(Collectors.toList());
                userService.deleteUserByBatch(userNumberForDel);
                flag = true;
            }
            //更新班级人数信息
            if (flag) {
                Integer number = clazzService.getStudentCountByClazzId(classId);
                clazz.setClassSize(number);
            }
            clazzService.updateClazz(clazz);
        } catch (TeachingException e) {
            return ResultVOUtil.fail(e.getCode(), e.getMessage());
        }
        return ResultVOUtil.success();
    }

}
